/*******************************************************************************
* file  : rsa key text
* creat : apleilx
* data  : 2017/03/02
*******************************************************************************/
#include "common.h"
#include "sys_task.h"
#include "os_obj.h"
#include "mbedtls/rsa.h"
#include "mbedtls/entropy.h"
#include "mbedtls/ctr_drbg.h"
#include "mbedtls/platform.h"
#include "mbedtls/bignum.h"

extern uu8 * rsa_key_N;
extern uu8 * rsa_key_E;
extern uu8 * rsa_key_D;
extern uu8 * rsa_key_P;
extern uu8 * rsa_key_Q;

extern void * rsa_src, *rsa_enc, *rsa_dec;

void ras_ext_verify(void);
void ras_ext_sign(void);

#define DEV_RANDOM_THRESHOLD        32
int rsa_random_entropy_poll( void *, unsigned char *, size_t, size_t *);
static const char pers[] = "simple_rsa";


/*
********************************************************************************
*                              assert
*******************************************************************************/
#define assert_exit(cond, ret) \
    do { if (!(cond)) { \
        dbg_print("  !. assert: failed [line: %d, error: -0x%04X]\n", __LINE__, -ret); \
        goto cleanup; \
    } } while (0)

	
/*******************************************************************************
* @brief  priv enc.
* \param[in] none
* \retval: none
*******************************************************************************/
void ras_priv_sign(void)
{
	dbg_print("\n\n");
	dbg_print("======================================\n");
	dbg_print("privite key sign, public key verify \n");
	dbg_print("======================================\n");
	ras_ext_sign();
	ras_ext_verify();
}


void ras_ext_sign(void)
{
	int ret;
	
    mbedtls_rsa_context *ctx;
    mbedtls_entropy_context *entropy;
    mbedtls_ctr_drbg_context *ctr_drbg;
	
	memset(rsa_src, 0, 400);
	loop_n(100) ((uu16 *)(rsa_src))[index] = index;
	
	entropy = malloc(sizeof(mbedtls_entropy_context));
	ctr_drbg = malloc(sizeof(mbedtls_ctr_drbg_context));
	ctx = malloc(sizeof(mbedtls_rsa_context));
	
    //rsa结构体初始化
    mbedtls_rsa_init(ctx);  
    mbedtls_entropy_init(entropy);
    mbedtls_ctr_drbg_init(ctr_drbg);
	
	// 填充方案OAEP //SHA256做散列算法
    mbedtls_rsa_set_padding(ctx, MBEDTLS_RSA_PKCS_V21, MBEDTLS_MD_SHA256);
	
	// 随机数生成器
	ret = mbedtls_entropy_add_source( 
		entropy, 
		rsa_random_entropy_poll,
		NULL, 
		DEV_RANDOM_THRESHOLD,
		MBEDTLS_ENTROPY_SOURCE_STRONG );
	
	assert_exit(ret == 0, ret);
	
    ret = mbedtls_ctr_drbg_seed(
		ctr_drbg, 
		mbedtls_entropy_func, 
		entropy, 
        (const uint8_t *) pers, 
		strlen(pers));				//根据个性化字符串更新种子
	
    assert_exit(ret == 0, ret);
	
	// 导入KEY
	ret = mbedtls_rsa_import_raw(ctx, 
		rsa_key_N, 1024/8,
		rsa_key_P, 1024/8/2,
		rsa_key_Q, 1024/8/2,
		rsa_key_D, 1024/8,
		rsa_key_E, 16
		);	

	ret += mbedtls_rsa_complete(ctx);
	assert_exit(ret == 0, ret);
		
    //RSA用私钥签名 输出sig签名结果
	ret = mbedtls_rsa_pkcs1_sign(
		ctx, 
		mbedtls_ctr_drbg_random, 
		ctr_drbg, 
		MBEDTLS_MD_NONE,
		100, 
		rsa_src, 
		rsa_enc);
   
    assert_exit(ret == 0, ret); 
	dbg_print("rsa signed ok\n");   

cleanup:
    mbedtls_ctr_drbg_free(ctr_drbg);	//释放随机数结构体
    mbedtls_entropy_free(entropy);		//释放熵结构体
    mbedtls_rsa_free(ctx);				//释放rsa结构体

	// 释放内存
	free(ctx);
	free(entropy);
	free(ctr_drbg);
}

void ras_ext_verify(void)
{
	int ret;
	uu32 olen;
	
    mbedtls_rsa_context *ctx;
    mbedtls_entropy_context *entropy;
    mbedtls_ctr_drbg_context *ctr_drbg;
	
	entropy = malloc(sizeof(mbedtls_entropy_context));
	ctr_drbg = malloc(sizeof(mbedtls_ctr_drbg_context));
	ctx = malloc(sizeof(mbedtls_rsa_context));
	
	//RSA密钥对初始化
    mbedtls_rsa_init(ctx);
    mbedtls_entropy_init(entropy);
    mbedtls_ctr_drbg_init(ctr_drbg);
	
	// 填充方案OAEP //SHA256做散列算法
    mbedtls_rsa_set_padding(ctx, MBEDTLS_RSA_PKCS_V21, MBEDTLS_MD_SHA256);
	
	// 随机数生成器
	ret = mbedtls_entropy_add_source( 
		entropy, 
		rsa_random_entropy_poll,
		NULL, 
		DEV_RANDOM_THRESHOLD,
		MBEDTLS_ENTROPY_SOURCE_STRONG );
	
    ret = mbedtls_ctr_drbg_seed(
		ctr_drbg, 
		mbedtls_entropy_func, 
		entropy, 
		(const uint8_t *) pers, 
		strlen(pers));				//根据个性化字符串更新种子
	
    assert_exit(ret == 0, ret);
	
	// 导入KEY
	ret = mbedtls_rsa_import_raw(ctx, 
		rsa_key_N, 1024/8,
		NULL, 1024/8/2,
		NULL, 1024/8/2,
		NULL, 1024/8,
		rsa_key_E, 16
		);
		
	ret += mbedtls_rsa_complete(ctx);
	assert_exit(ret == 0, ret);
		
	
    //RSA公钥验签 返回0则验证成功
    ret = mbedtls_rsa_pkcs1_verify(
		ctx,  
		MBEDTLS_MD_NONE, 
		100, 
		rsa_src, 
		rsa_enc);
	dbg_assert_zero(ret, "rsa signed error");
	dbg_msg_zero(ret, "rsa signed ok");
	
	((uu16 *)(rsa_src))[40] = 81;
    ret = mbedtls_rsa_pkcs1_verify(
		ctx,  
		MBEDTLS_MD_NONE, 
		100, 
		rsa_src, 
		rsa_enc);
		
	dbg_msg_zero(ret, "rsa signed ok");
	dbg_assert_zero(ret, "rsa signed error");
	
    assert_exit(ret == 0, ret);
    dbg_print("rsa sign verify signature ... ok\n\n");                             
	

cleanup:
    mbedtls_ctr_drbg_free(ctr_drbg);	//释放随机数结构体
    mbedtls_entropy_free(entropy);		//释放熵结构体
    mbedtls_rsa_free(ctx);				//释放rsa结构体

	// 释放内存
	free(ctx);
	free(entropy);
	free(ctr_drbg);
}
